﻿using System;
using System.Data;

namespace YueRu.Common
{
    /// <summary>
    /// 处理C#数据类型和DataTable之间的转换
    /// </summary>
    public static class DataObjectFiller
    {
        /// <summary>
        /// 填充对象,DataRow的扩展方法
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="row"></param>
        /// <param name="rowName"></param>
        /// <returns></returns>
        public static T FillObject<T>(this DataRow row, string rowName)
        {
            return (T)GetColumnTypeObject(typeof(T), row, rowName);
        }

        private static object GetColumnTypeObject(Type type, DataRow dr, string columnName)
        {
            #region 取得每行对应的列的类型对象

            if (dr.Table.Columns.Contains(columnName) == false)
            {
                return null;
            }
            var value = dr[columnName];
            if (type == typeof(DateTime))
            {
                return (DateTime)value;
            }

            if (type == null)
                return value == null ? null : value.ToString();

            if (type == typeof(byte) || type == typeof(Byte))
            {
                return (value == null || value == DBNull.Value) ? byte.Parse("0") : byte.Parse(value.ToString());
            }

            if (type == typeof(sbyte))
            {
                return (value == null || value == DBNull.Value) ? sbyte.Parse("0") : sbyte.Parse(value.ToString());
            }

            if (type == typeof(byte[]) || type == typeof(Byte[]))
            {
                return (value == null || value == DBNull.Value) ? null : (byte[])value;
            }

            if (type == typeof(short))
            {
                return (value == null || value == DBNull.Value) ? short.Parse("0") : short.Parse(value.ToString());
            }

            if (type == typeof(int))
            {
                return (value == null || value == DBNull.Value) ? 0 : int.Parse(value.ToString());
            }

            if (type == typeof(long))
            {
                return (value == null || value == DBNull.Value) ? 0 : long.Parse(value.ToString());
            }

            if (type == typeof(decimal) || type == typeof(Decimal))
            {
                return (value == null || value == DBNull.Value) ? decimal.Parse("0") : decimal.Parse(value.ToString());
            }

            if (type == typeof(float))
            {
                return (value == null || value == DBNull.Value) ? 0 : float.Parse(value.ToString());
            }
            if (type == typeof(double) || type == typeof(Double))
            {
                return (value == null || value == DBNull.Value) ? 0 : double.Parse(value.ToString());
            }

            if (type == typeof(string) || type == typeof(String))
            {
                return (value == null || value == DBNull.Value) ? null : value.ToString();
            }

            if (type == typeof(bool) || type == typeof(Boolean))
            {
                var valueBool = false;
                if (value == null || value == DBNull.Value)
                {
                    return false;
                }
                if (value.ToString().Trim() == "1")
                {
                    return true;
                }
                bool.TryParse(value.ToString(), out valueBool);
                return valueBool;
            }

            if (type == typeof(Guid))
            {
                return (value == null || value == DBNull.Value) ? Guid.NewGuid() : (Guid)value;
            }

            if (type.IsEnum)
            {
                if (value == null || value == DBNull.Value)
                    return null;
                return Enum.Parse(type, value.ToString());
            }

            throw new ArgumentException("Can't convert type [" + type + "].", "type");
            #endregion
        }
    }
}